Skip to content

docs(pm-dispatch): 过滤/谓词语义裁决派发必须枚举编译面清单并逐面申报 (#6410) - #6464

Merged
hotlong merged 1 commit into
mainfrom
claude/issue-6410-semantic-ruling-compiler-faces
Aug 7, 2026
Merged

docs(pm-dispatch): 过滤/谓词语义裁决派发必须枚举编译面清单并逐面申报 (#6410)#6464
hotlong merged 1 commit into
mainfrom
claude/issue-6410-semantic-ruling-compiler-faces

Conversation

@hotlong

@hotlong hotlong commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #6410

#5930 裁决的流程半边。纯 SKILL 文本改动,不碰任何编译器 / 求值器代码。


0. 前置:串行链头 #5925 的分支核实(分诊 17:55Z 点名)

分诊列出四张卡同落 .claude/skills/pm-dispatch/SKILL.md,并指 #5925(pm:dispatched、assignee 非本座位)为链头。动笔前核实:

git ls-remote --heads origin | grep -c '5925'   →  0

结论:origin 上不存在 #5925 的分支。 首次 grep 曾出现一条疑似命中,复核后是 SHA 里的 5925 子串(fa68ce39ba55925d6… refs/heads/claude/peaceful-allen-aZ1ir),不是分支名 —— 这正是「照抄第一眼结果」会出错的一处,故记录在此。

补充核实:全部远端分支名里没有任何 issue-5925 / sediment 形状的分支;当前仓库仅 2 个 open PR(#6208 changeset-release、#6461 spec 锚点),都不触及本文件

#5925 的落点不相交(它没有在飞编辑),正常推进。⛔ 未改其状态、未认领、未催。


1. 条款落点(before / after)

落在 step 5 派发提示词指引区,紧接「拒收类用例的最低断言集」条款之后、「Issue 正文是线索」之前 —— 与该区已有的两条「派发令的标准条款」同构(同样的 适用判据 → 原话 blockquote → 理由 骨架)。

before(origin/main): step 5 只有一条相邻条款「多面组件:测试落点是共享一致性覆盖」(1342–1362 行)。它管的是测试往哪放,不管清单申报

after: 新增常设条款,含 (a) 派发令必须枚举完整编译面清单,(b) PR 必须逐面申报「已改 / 本就合规(给证据)/ 明确不在范围(给理由)」,(c) 清单由 PR 维护(与域表同一纪律),(d) 派发前必须复核再抄。

关键一句(原话,进派发令):

本单改的这条语义由多个互相独立的编译器 / 求值器各自实现。派发令列出的每一面都必须在你的 PR 正文里有一个结论:已改 / 本就合规(给出证据)/ 明确不在范围(给出理由)。⛔ 不许静默略过 —— 评审把「没提到的面」一律读作「漏掉的面」,不读作「不需要改」。

文本形状参照 #5298 §1(已读原文):该节把每个实现面逐行列进一张表、每格是实测结论而非叙述。本条款的清单沿用这个形状。


2. 逐面只读核实(⛔ 未照抄卡片,全部实测 @ main 48f98b0)

# 实测 file:line 与卡片是否一致
1 driver-sql packages/drivers/driver-sql/src/sql-driver.ts:7083(applyFilterCondition);NULL-safe 段 :1483 ⚠️ 路径不符:卡片写 sql-driver.ts,实际在 packages/drivers/
1-继承 wasm / turso-local driver-sqlite-wasm/src/sqlite-wasm-driver.ts:67driver-turso/src/turso-driver.ts:174,均 extends SqlDriver ✅ 卡片「wasm / turso-local 继承」成立
2 turso RemoteTransport packages/drivers/driver-turso/src/remote-transport.ts:1526(private buildWhereSQL) ✅ 成立
3 service-analytics read-scope-sql packages/services/service-analytics/src/read-scope-sql.ts:259(compileScopedFilterToSql) ⚠️ 路径不符:实际在 packages/services/
4 service-analytics filter-normalizer packages/services/service-analytics/src/strategies/filter-normalizer.ts:1235(lowerAnalyticsWhere) ⚠️ 同上,且在 strategies/ 子目录
5 formula packages/formula/src/matches-filter.ts:73(matchesFilterCondition) ✅ 成立
半面 objectql having-filter packages/objectql/src/having-filter.ts:92 / :98(applyHaving / matchesHaving) ✅ 成立
冻结 driver-memory / driver-mongodb 冻结注释实测在 read-scope-sql.ts:176having-filter.ts:41objectql/src/filter-comparand-shape.ts:41 #5499 冻结状态未变,仍是 pin-annotate

与卡片的差异(以实测为准,已反映进 SKILL 清单):

  1. 三处包路径已搬家 —— 驱动进 packages/drivers/、服务进 packages/services/,filter-normalizer 还在 strategies/ 子目录。卡片给的是裸文件名,照抄进派发令会指向不存在的路径。已把完整路径 + 行号写进清单,并在条款里加了一句「⛔ 不要凭这张表的记忆填派发令 + 复核 grep 串」。
  2. 多出一次历史复发 —— 卡片举了两例($not 的语义在 driver-sql 与 driver-memory / formula 之间分叉:NULL 行的去留相反,$not: {} 一个是 TRUE 一个是 FALSE #5146drivers(turso): remote 模式没有继承 #5146 的 $not NULL-safe —— 同一个 TursoDriver,local 返回 NULL 行、remote 不返回(实测,origin/main) #5903fix(service-analytics): read scope 的 { $not: {} } 不再整表放行,$not 改为 NULL-safe (#5297) #5326/fix(service-analytics)!: 作者的 where 也 NULL-safe —— $not 下推守卫、{$not:{}} 为零行、{} 析取项吸收 $or (#5325) #5335),实测代码注释里有第三例且最新:objectql/src/having-filter.ts:37 原话是 HAVING 面「was not in that PR's inventory, which left this file as the lone holdout」(非否定路径上的 $ne / $nin / $notContains:driver-sql 排除 NULL 行,driver-memory / formula 返回它们(#5146 只裁定了 $not) #5298 的裁决由 PR fix(drivers,analytics,formula): $ne / $nin / $notContains 在 $not 之外也 NULL-safe (#5298) #5962 落地时漏掉)。这一例的判别力最强 —— 那次派发确实有一份 inventory,只是不完整,而没有任何机制要求它完整,正是本条款要补的位置。已写进条款理由。
  3. 半面的措辞 —— 卡片称 having-filter 为「半面」,而代码注释称它是 "the FIFTH evaluation face"(两者计数基准不同)。清单保留「半面」标注但写明申报义务不打折,并记下它是唯一没有 conformance 表覆盖的面(FILTER_LOGIC_CASES 不驱动 HAVING 路径)⇒ 漏了它连门禁都不会红。

3. 反向验证(先申报,后执行)

⚠️ 纯文本纪律改动,无可执行运行时 ⇒ 模板式「改前红 / 改后绿」不适用,未硬套伪造一个红。改为下面三条申报。每条标明实测还是论证。

声明 A — 条款可判定(本单唯一有判别力的验证)

申报: 把三个真实历史漏面案例代入,比较旧文本与新条款各给出什么判断。

A-1(实测):旧文本给不出「逐面申报」这个判断。origin/main 的内部 SKILL 上逐 token 计数:

token origin/main 本分支
编译面 0 2
逐面 0 2
每一面 0 1
本就合规 0 1
buildWhereSQL / matchesFilterCondition / having-filter 0 / 0 / 0 2 / 2 / 3

origin/main实现面 仅 3 处命中(1343 / 1346 / 1361),全部属于「多面组件:测试落点」那条测试放置条款 —— 它要求的是「新用例进共享一致性覆盖」,不是「清单」也不是「申报」。

⚠️ 一处容易误读的命中,如实记录:origin/main申报 有 7 处命中(464 / 500 / 503 / 743 / 751–753 / 1698 / 2215),但读上下文全部是 PM 跨座位的「文件面申报」防撞协议(申报本单碰哪些文件,避免两个 PM 撞车),与「一条语义的哪几个实现面各自什么结论」是两个概念。⇒ 旧文本确实零覆盖。

A-2(论证,非实测):新条款对三例的判断。 历史不可重跑,以下是把条款文本代入的推演:

案例 旧文本的判断 新条款的判断
#5146#5903 面 2 是独立编译器,与面 1 无代码共享。旧文本只问「测试放哪」⇒ 只改面 1 且把用例放进共享表,读起来完全合规 派发令列出面 2,PR 必须对它给结论。面 2 既非「已改」也非「本就合规」⇒ 只能写「不在范围 + 理由」,该理由在评审时就会被看见,而不是几周后变成 #5903
#5326 / #5335 同上,面 3 / 面 4 无人过问 ⇒ 各自晚一圈 两面在原裁决的派发令里就被点名,晚来的两圈合并进第一圈
#5905 那次派发已经有 inventory,旧文本对 inventory 的完整性无任何要求 ⇒ 漏 HAVING 面不违反任何条款 清单是常设由 PR 维护;HAVING 面在表内,漏掉即违反申报义务

A-3(实测):证据出处不是我的转述。 三例的成因都写在代码注释里,已逐条读原文:

A 结论: 判别力成立。A-1 / A-3 为实测,A-2 为论证 —— 不把 A-2 写成实测。

声明 B — 清单与实测一致

申报: 逐面 grep,证据表见上文第 2 节,含 3 处与卡片不符之处。结果:实测通过,SKILL 里的清单反映的是实测现状(完整路径 + 行号)而非卡片原文。

声明 C — 三轴框架逐字节相同

见下节。结果:实测通过。


4. 三轴决策框架:diff / cmp / md5 三重取证

⚠️ 直接按行号截取会被本 PR 的插入整体位移,故用内容锚点提取 4 份拷贝(锚点镜像 scripts/check-skill-frame-sync.mjsCOPIES 表)后再比对。

拷贝 md5 BEFORE md5 AFTER cmp diff 行号位移
internal-pm b321fc62…d1dd b321fc62…d1dd EXIT=0 0 行 2109 → 2158(+49)
internal-dev 82007420…7af2 82007420…7af2 EXIT=0 0 行 277 → 277(未动该文件)
published-pm 8d7c83d1…c5a3 8d7c83d1…c5a3 EXIT=0 0 行 607 → 644(+37)
published-dev 55007a96…3700 55007a96…3700 EXIT=0 0 行 764 → 801(+37)

4/4 逐字节相同。 位移量与两处插入的行数(内部 +49、发布件 +37)精确吻合,即位移全部来自本 PR 的新增段落,frame 段本身未被触碰。.claude/agents/os-dev.md 完全未改

⚠️ check:skill-frame-freshness 末行读作 1/3 framework files are byte-identical,这不是 frame 漂移。 该计数按整份文件计而非 frame 段,本 PR 同时改了 3 份 frame-bearing 文件中的 2 份 ⇒ 必然显示 1/3,gate 仍 EXIT=0#6460 已实测并在其 PR 正文澄清过同一现象。


5. 发布件核实(#5451 route B)

核实结论:发布件有同构的 step 5 面 —— skills/objectstack-pm-dispatch/SKILL.md:377 ### 5. Dispatch,结构与内部件一致(派发令模板 + #### Dispatch backends 子节)⇒ 按 route B 加泛化版,插在派发令模板之后、#### Dispatch backends 之前。

泛化写法(实测约束,非假设):

约束 实测 本 PR 是否守住
发布件无 lane / seat / domain: 词汇作为本仓术语 各 1 处,均为通用语境 一处都没新增
发布件是英文、无 派发令 / 标准条款 等中文术语(计数 0) 确认 0 ✅ 新段落全英文
⚠️ role 词计数必须仍为 0 BEFORE 0 → AFTER 0 check:role-word EXIT=0
⛔ 不带本仓 issue 号 #59 / #51 计数 0 → 0
⛔ 不带本仓具体文件名 buildWhereSQL / sql-driver 计数 0 → 0

发布件只写机制:「a semantic rule implemented more than once by compilers or evaluators that share no code ⇒ the prompt carries an explicit inventory of every implementing surface, and the agent gives a verdict for each one」,外加两条同样通用的纪律(inventory 由 PR 维护 / 粘贴前重新核对)与冻结面仍需申报。


6. 门禁 EXIT 表(git add 之后跑)

门禁 改前 改后
pnpm check:skill-frame-sync EXIT=0(12 self-test + 4 拷贝同构) EXIT=0(同上)
pnpm check:skill-frame-freshness EXIT=0 EXIT=0(1/3 见上节说明)
pnpm check:doc-authoring EXIT=0(365 files clean)
pnpm check:role-word EXIT=0(44 baselined, no new occurrences)
pnpm check:nul-bytes EXIT=0(6089 tracked files, no raw control bytes)
控制字节自扫(grep -naP,NUL 之外的全部扫描面) 无命中(两份文件)
pnpm check:published-files EXIT=0
pnpm check:skill-compatibility EXIT=0(11 SKILL.md 对账)
pnpm check:quick-reference-counts EXIT=0
pnpm check:docs-audit-scope EXIT=0
pnpm check:adr-anchors EXIT=0

⚠️ 偏差记录:派发令里点名的 pnpm check:skill-docs 在本仓不存在。 实测 package.json 无该 script;.github/workflows/lint.yml 里也没有。已按 os-dev 规程从 lint.yml 逐个列门,补跑了发布件相关的真实门禁:check:published-filescheck:skill-compatibilitycheck:quick-reference-countscheck:docs-audit-scopecheck:adr-anchors(见表)。


7. Changeset

—— 纯文档、不发布任何包(.claude/** 不进任何包;skills/** 非 npm 发布物)⇒ 路线 2,PR 创建后立即加 skip-changeset 标签。


8. ⛔ 不在本 PR 里


Generated by Claude Code

#5930 裁决的流程半边:一个 `FilterCondition` 语义由 5 个互相独立的编译器/求值器
承载,每条语义裁决成本 ×5,而漏面反复复发 —— #5146 漏面 2 变成 #5903#5326 /
#5335 各花一圈补齐面 3/4、PR #5962 的 inventory 漏掉 HAVING 面变成 #5905。

在 step 5 派发提示词指引区加一条常设条款:凡过滤/谓词语义裁决,派发令必须枚举
完整编译面清单,dev 的 PR 必须逐面申报「已改 / 本就合规 / 明确不在范围(带理由)」;
清单本身由 PR 维护,与域表同一纪律。清单为逐面实测(file:line @ main 48f98b0),
非照抄卡片 —— 路径已搬家(驱动进 packages/drivers/、服务进 packages/services/)。

发布件按 #5451 route B 加泛化版:只写机制(「一个语义由 N 个独立实现承载时,派发
必须枚举全部承载面并要求逐面申报」),不带本仓 issue 号与文件名。

三轴决策框架未触碰:4 份拷贝逐字节相同(diff/cmp/md5 三重取证)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 7, 2026 11:25pm

Request Review

@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Aug 7, 2026
@hotlong hotlong added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed documentation Improvements or additions to documentation labels Aug 7, 2026 — with Claude
@hotlong
hotlong marked this pull request as ready for review August 7, 2026 23:34
@hotlong
hotlong added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 7a83795 Aug 7, 2026
26 checks passed
@hotlong
hotlong deleted the claude/issue-6410-semantic-ruling-compiler-faces branch August 7, 2026 23:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[skill] pm-dispatch: semantic-ruling template must carry a compiler-face checklist — process half of the #5930 ruling

2 participants